package com.gitee.srurl.system.interceptor;

import cn.hutool.core.util.StrUtil;
import com.gitee.srurl.core.annotation.Login;
import com.gitee.srurl.core.constant.GlobalConstant;
import com.gitee.srurl.core.enums.ResponseCodeEnums;
import com.gitee.srurl.core.util.JacksonUtil;
import com.gitee.srurl.core.util.JwtUtil;
import com.gitee.srurl.core.util.ServletUtil;
import com.gitee.srurl.core.util.login.LoginHelper;
import com.gitee.srurl.core.util.login.OperationUser;
import com.gitee.srurl.system.util.response.R;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * @author zxw
 * @date 2023/4/9 17:26
 */
@Slf4j
@Component
public class LoginHandlerInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if (!(handler instanceof HandlerMethod handlerMethod)) {
            return true;
        }

        Login login = handlerMethod.getMethodAnnotation(Login.class);
        if (login == null) {
            return true;
        }
        // 获取token
        String token = request.getHeader(GlobalConstant.AUTHORIZATION);
        if (StrUtil.isBlank(token)) {
            ResponseCodeEnums tokenNotSupport = ResponseCodeEnums.TOKEN_NOT_SUPPORT;
            R<Void> r = R.error(tokenNotSupport.code(), tokenNotSupport.message());
            response.getOutputStream().write(JacksonUtil.toJsonByte(r));
            return false;
        }
        if (StrUtil.startWith(token, GlobalConstant.TOKEN_BEARER)) {
            token = StrUtil.sub(token, GlobalConstant.TOKEN_BEARER.length(), token.length());
        }
        // 解析token
        OperationUser operationUser = JwtUtil.parseTokenAndVerify(token);
        Boolean isApiUser = operationUser.getApi();
        if (isApiUser == null) {
            log.info("userId:{},是否api用户身份信息异常", operationUser.getUserId());
            ServletUtil.renderString(response, JacksonUtil.toJsonString(R.error("用户身份信息异常")));
            return false;
        }

        Login.ApiAccess apiAccess = login.apiAccess();
        if (apiAccess == Login.ApiAccess.USER) {
            // 不允许api用户访问
            if (operationUser.getApi()) {
                log.info("api用户禁止访问普通接口");
                ServletUtil.renderString(response, JacksonUtil.toJsonString(R.error("权限不足")));
                return false;
            }
        } else if (apiAccess == Login.ApiAccess.API){
            if (!operationUser.getApi()) {
                log.info("api接口不允许用户访问");
                ServletUtil.renderString(response, JacksonUtil.toJsonString(R.error("权限不足")));
                return false;
            }
        }

        LoginHelper.setLoginUser(operationUser);

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        LoginHelper.removeLoginUser();
    }
}
